package cn.sylinx.common.ext.web;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.sylinx.common.lang.StringUtil;

/**
 * xhr2 filter配置
 * 
 * @author han
 *
 */
public class Xhr2Filter extends BaseFilter {

	private String allowOrigin = "*";
	private String allowMethods = "GET,POST,PUT,DELETE";
	private String allowHeaders = "Origin, X-Requested-With, X_Requested_With, Content-Type, Accept, Cache-Control, Session-Token";
	private String originReg = null;
	private String contentType = null; // "Content-Type", "application/json;charset=utf-8"

	public void setAllowOrigin(String allowOrigin) {
		this.allowOrigin = allowOrigin;
	}

	public void setAllowMethods(String allowMethods) {
		this.allowMethods = allowMethods;
	}

	public void setAllowHeaders(String allowHeaders) {
		this.allowHeaders = allowHeaders;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public void setOriginReg(String originReg) {
		this.originReg = originReg;
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;
		String origin = req.getHeader("Origin");
		String allowOriginTemp = match(origin) ? origin : allowOrigin;

		if (response instanceof HttpServletResponse) {

			HttpServletResponse rsp = (HttpServletResponse) response;
			rsp.setHeader("Access-Control-Allow-Origin", allowOriginTemp);
			rsp.setHeader("Access-Control-Allow-Methods", allowMethods);
			rsp.setHeader("Access-Control-Allow-Headers", allowHeaders);
			if (StringUtil.isNotBlank(contentType)) {
				rsp.setHeader("Content-Type", contentType);
			}

		}

		if ("OPTIONS".equalsIgnoreCase(req.getMethod())) {
			// 是否支持跨域
			write(response, Result.apply("2000", "OK"));
			return;
		}

		chain.doFilter(request, response);
	}

	private boolean match(String origin) {
		if (StringUtil.isBlank(origin)) {
			return false;
		}

		if (StringUtil.isBlank(originReg)) {
			return false;
		}

		Pattern p = Pattern.compile(originReg);
		Matcher m = p.matcher(origin);
		return m.matches();
	}
}
